﻿using System;
using System.Threading;
using System.Threading.Tasks;
using WholeSlideImageLibrary;
using WholeSlideImageViewer.OptiExport;
using WholeSlideImageViewer.TiffExport;

namespace WholeSlideImageViewer.Services
{
    internal class ExportService : IExportService
    {
        public async Task<IExportProgress> ExportTiffAsync(RetainableDeepZoomGenerator deepZoom, ITiffOutputOptions options, string outputFileName, CancellationToken cancellationToken)
        {
            TiffExporter? exporter = new TiffExporter(options, outputFileName);
            try
            {
                WholeSlideImage? image = deepZoom.Image;
                if (image is null)
                {
                    throw new InvalidOperationException();
                }
                await exporter.InitializeAsync(image, cancellationToken);
                TiffExportProgress progress = exporter.Progress;
                TiffExporter? exporterInstance = exporter;
                exporter = null;

                _ = Task.Run(async () =>
                {
                    try
                    {
                        await exporterInstance.RunAsync(cancellationToken).ConfigureAwait(false);
                    }
                    finally
                    {
                        await exporterInstance.DisposeAsync().ConfigureAwait(false);
                    }
                });
                return progress;
            }
            finally
            {
                if (!(exporter is null))
                {
                    await exporter.DisposeAsync().ConfigureAwait(false);
                }
            }
        }

        public async Task<IExportProgress> ExportOptiAsync(RetainableDeepZoomGenerator deepZoom, IOptiOutputOptions options, string outputFileName, CancellationToken cancellationToken)
        {
            OptiExporter? exporter = new OptiExporter(options, outputFileName);
            try
            {
                WholeSlideImage? image = deepZoom.Image;
                if (image is null)
                {
                    throw new InvalidOperationException();
                }
                await exporter.InitializeAsync(image, cancellationToken);
                OptiExportProgress progress = exporter.Progress;
                OptiExporter? exporterInstance = exporter;
                exporter = null;

                _ = Task.Run(async () =>
                {
                    try
                    {
                        await exporterInstance.RunAsync(cancellationToken).ConfigureAwait(false);
                    }
                    finally
                    {
                        await exporterInstance.DisposeAsync().ConfigureAwait(false);
                    }
                });
                return progress;
            }
            finally
            {
                if (!(exporter is null))
                {
                    await exporter.DisposeAsync().ConfigureAwait(false);
                }
            }
        }
    }
}
